package com.sxkf.template.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sxkf.core.common.ali.AliPayUtil;
import com.sxkf.core.common.wx.WxPayUtils;
import com.sxkf.core.constant.CommonConstant;
import com.sxkf.system.entity.SysUser;
import com.sxkf.system.mapper.SysUserMapper;
import com.sxkf.template.service.*;
import com.sxkf.template.vo.request.order.DeliverOrderVo;
import org.jeecg.common.exception.SxkfException;
import org.jeecg.common.exception.SxkfExceptionEnum;
import org.jeecg.common.util.CheckEmptyUtil;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.RedisUtils;
import com.sxkf.template.constants.OrderConstant;
import com.sxkf.template.entity.*;
import com.sxkf.template.mapper.*;
import com.sxkf.template.utils.OrderUtil;
import com.sxkf.template.vo.request.order.CreateOrderVo;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import static java.math.BigDecimal.ROUND_HALF_UP;

@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private UserMapper userMapper;
    @Resource
    private ShoppingCartMapper shoppingCartMapper;
    @Resource
    private ProductMapper productMapper;
    @Resource
    private ProductSpecMapper productSpecMapper;
    @Resource
    private OrderDetailService orderDetailService;
    @Resource
    private OrderDetailMapper orderDetailMapper;
    @Resource
    private AddressMapper addressMapper;
    @Resource
    private OrderRecipientMapper orderRecipientMapper;
    @Resource
    private UserCouponMapper userCouponMapper;
    @Resource
    private StoreMapper storeMapper;
    @Resource
    private SpellOutService spellOutService;
    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private RefundService refundService;
    @Autowired
    private AfterSaleOrderMapper afterSaleOrderMapper;
    @Autowired
    private MessageService messageService;
    @Resource
    private SysConfigService sysConfigService;
    @Resource
    private AmountRecordService amountRecordService;


    @Override
    public String createOrderByCart(CreateOrderVo createOrderVo) {
        //查询用户
        User user = userMapper.selectById(createOrderVo.getUserId());
        if (user == null) {
            throw new SxkfException("用户异常");
        }

        //查询购物车
        List<ShoppingCart> shoppingCarts = shoppingCartMapper.selectBatchIds(createOrderVo.getCheckIds());
        log.info("用户购物车：{}", shoppingCarts);
        if (CheckEmptyUtil.isEmpty(shoppingCarts)) {
            throw new SxkfException(SxkfExceptionEnum.USER_SHOPPING_CART_ERROR);
        }

        //查询地址
        Address address = addressMapper.selectById(createOrderVo.getAddressId());
        if (address == null){
            throw new SxkfException("地址异常");
        }

        //查询优惠券
        UserCoupon userCoupon = null;
        if (!createOrderVo.getUserCouponId().equals("0")) {
            userCoupon = userCouponMapper.selectById(createOrderVo.getUserCouponId());
        }

        List<Order> orders = new ArrayList<>();

        BigDecimal totalPrice = BigDecimal.ZERO;
        Map<String, List<ShoppingCart>> shoppingCartMap = shoppingCarts.stream().collect(Collectors.groupingBy(ShoppingCart::getStoreId));
        for (Map.Entry<String, List<ShoppingCart>> entry : shoppingCartMap.entrySet()) {
            List<ShoppingCart> value = entry.getValue();
            Order order = initOrder(createOrderVo);

            int productTotal = value.stream().mapToInt(ShoppingCart::getCount).sum();
            order.setProductTotal(productTotal);

            //获取购物车的价格
            BigDecimal shoppingCartPrice = BigDecimal.ZERO;
            List<OrderDetail> orderDetails = new ArrayList<>();

            BigDecimal freight = BigDecimal.ZERO;

            for (ShoppingCart shoppingCart : value) {
                Product product = productMapper.selectById(shoppingCart.getProductId());
                if (CheckEmptyUtil.isEmpty(product)) {
                    throw new SxkfException(500, "商品不存在");
                }
                ProductSpec productSpec = productSpecMapper.selectById(shoppingCart.getProductSpecId());
                if (productSpec.getStock() <= 0) {
                    throw new SxkfException(500, "商品库存不足");
                }
                BigDecimal productPrice = productSpec.getSalePrice();
                //添加订单详情
                OrderDetail orderDetail = getOrderDetail(shoppingCart.getCount(), product, productSpec);
                orderDetail.setUserId(order.getUserId());
                orderDetails.add(orderDetail);

//                Store store = storeMapper.selectById(orderDetail.getStoreId());
//                // 计算运费
//                freight = freight.add(store.getFreight());

                //添加商品销量
                product.setSaleCount(product.getSaleCount() + shoppingCart.getCount());
                //减少商品库存
                productSpec.setStock(productSpec.getStock() - shoppingCart.getCount());
                productMapper.updateById(product);
                productSpecMapper.updateById(productSpec);
                //计算购物车价格
                shoppingCartPrice = shoppingCartPrice.add(productPrice.multiply(BigDecimal.valueOf(shoppingCart.getCount())));
            }

            Store store = storeMapper.selectById(value.get(0).getStoreId());
            // 计算运费
            freight = freight.add(store.getFreight());

            //订单总价
            BigDecimal orderTotalPrice = shoppingCartPrice;

            //计算优惠券
            if (userCoupon != null && entry.getKey().equals(userCoupon.getStoreId())){
                orderTotalPrice = handleCoupon(shoppingCartPrice, userCoupon, order);
            }

            // 计算运费需要修改(跟客户确认逻辑)

//            log.info("运费  前端计算:{}后端计算价格:{}",createOrderVo.getTotalPrice(),orderTotalPrice);
//            if (!freight.equals(createOrderVo.getOrderFreight())){
//                throw new SxkfException(SxkfExceptionEnum.PAY_ERROR);
//            }


//            BigDecimal freight = BigDecimal.ZERO;


            orderTotalPrice = orderTotalPrice.add(freight);

            order.setStoreId(entry.getKey());
            order.setFreight(freight);
            order.setProductTotalPrice(shoppingCartPrice);
            order.setOrderTotalPrice(orderTotalPrice);
            order.setAddressId(address.getId());
            save(order);

            orders.add(order);

            orderDetails.forEach(item -> item.setOrderId(order.getId()));
            orderDetailService.saveBatch(orderDetails);

            OrderRecipient orderRecipient = new OrderRecipient();
            BeanUtils.copyProperties(address, orderRecipient,"id");
            orderRecipient.setOrderId(order.getId());
            orderRecipientMapper.insert(orderRecipient);

            totalPrice = totalPrice.add(orderTotalPrice);
        }

        if (createOrderVo.getTotalPrice().compareTo(totalPrice) != 0) {
            throw new SxkfException(SxkfExceptionEnum.PAY_ERROR);
        }

        if (totalPrice.compareTo(BigDecimal.ZERO) <= 0) {
            //直接走回调并通知前端支付成功
            orders.forEach(this::paySuccess);
            return null;
        }

        String result;
        if ("WX".equals(createOrderVo.getPayType())) {
            result = WxPayUtils.createOrderV3(OrderUtil.creatOrder(), totalPrice, "", null);
        } else if ("ZFB".equals(createOrderVo.getPayType())) {
            result = AliPayUtil.pay("", OrderUtil.creatOrder(), totalPrice);
        } else if (createOrderVo.getPayType().equals("YUE")){

            if (user.getAmount().compareTo(totalPrice) < 0){
                throw new SxkfException("余额不足");
            }

            user.setAmount(user.getAmount().subtract(totalPrice));
            int updateUserAmount = userMapper.updateById(user);
            if (updateUserAmount == 0){
                throw new SxkfException("余额支付失败");
            }
            // 存记录
            AmountRecord amountRecord = new AmountRecord();
            amountRecord.setUserId(user.getId());
            amountRecord.setIsAdd("0");
            amountRecord.setPrice(totalPrice);
            amountRecord.setRemark("余额支付");
            amountRecordService.save(amountRecord);

            orders.forEach(this::paySuccess);
            result = "success";
        }else {
            throw new SxkfException(SxkfExceptionEnum.PAY_TYPE_ERROR);
        }
        return result;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createOrderSingle(CreateOrderVo createOrderVo) {
        User user = userMapper.selectById(createOrderVo.getUserId());
        if (user == null) {
            throw new SxkfException("用户异常");
        }

        Product product = productMapper.selectById(createOrderVo.getProductId());
        ProductSpec productSpec = productSpecMapper.selectById(createOrderVo.getProductSpecId());
        if (product == null || productSpec == null){
            throw new SxkfException("商品信息异常");
        }

        if ("1".equals(createOrderVo.getIsTeam())){
            spellOutService.checkProduct(product);
            if (!"0".equals(createOrderVo.getSpellOutId())){
                SpellOut spellOut = spellOutService.getById(createOrderVo.getSpellOutId());
                if (null == spellOut){
                    throw new SxkfException("拼团信息已失效");
                }
                spellOutService.checkJoin(createOrderVo.getUserId(),spellOut);
//            }else {
//                // 开团
//                SpellOut spellOut = new SpellOut();
//                spellOut.setCreateId(createOrderVo.getUserId());
//                spellOut.setProductId(product.getId());
//                spellOutService.create(spellOut);
            }

        }



        BigDecimal productPrice = "1".equals(createOrderVo.getIsTeam())?productSpec.getTeamPrice():productSpec.getSalePrice();
        BigDecimal orderTotalPrice = productPrice.multiply(BigDecimal.valueOf(createOrderVo.getProductCount()));


        Order order = initOrder(createOrderVo);
        order.setStoreId(product.getStoreId());
        order.setProductTotal(createOrderVo.getProductCount());
//        order.setProductTotalPrice(orderTotalPrice);
        order.setPayType(createOrderVo.getPayType());

        //添加商品销量
        product.setSaleCount(product.getSaleCount() + createOrderVo.getProductCount());
        productMapper.updateById(product);

        //减少商品库存
        if (productSpec.getStock() <= 0) {
            throw new SxkfException(500, "商品库存不足");
        }
        productSpec.setStock(productSpec.getStock() - createOrderVo.getProductCount());
        productSpecMapper.updateById(productSpec);

        OrderDetail orderDetail = getOrderDetail(createOrderVo.getProductCount(), product, productSpec);


        // 计算运费需要修改

        // 获取运费
        Store store = storeMapper.selectById(product.getStoreId());
        order.setFreight(store.getFreight());

        if (!CheckEmptyUtil.isEmpty(createOrderVo.getFreight())){
            orderTotalPrice = orderTotalPrice.add(createOrderVo.getFreight());
        }

        order.setProductTotalPrice(orderTotalPrice);

        // 获取运费
//        Store store = storeMapper.selectById(product.getStoreId());
        log.info("总价  前端计算:{}后端计算价格:{}",createOrderVo.getTotalPrice(),orderTotalPrice);
        log.info("运费  前端计算:{}后端计算价格:{}",createOrderVo.getFreight(),store.getFreight());
        BigDecimal freight = createOrderVo.getFreight().setScale(2, RoundingMode.HALF_UP);
        if (!store.getFreight().equals(freight)){
//            throw new SxkfException(500,"商品总价(需前端进行计算):"+createOrderVo.getTotalPrice()+"后端计算价格:"+orderTotalPrice);
            throw new SxkfException(SxkfExceptionEnum.PAY_ERROR);
        }



//        if (!CheckEmptyUtil.isEmpty(createOrderVo.getOrderFreight())){
//            orderTotalPrice = orderTotalPrice.add(createOrderVo.getOrderFreight());
//        }
//
//        // 获取运费
//        Store store = storeMapper.selectById(product.getStoreId());
//        log.info("总价  前端计算:{}后端计算价格:{}",createOrderVo.getTotalPrice(),orderTotalPrice);
//        log.info("运费  前端计算:{}后端计算价格:{}",createOrderVo.getOrderFreight(),store.getFreight());
//        if (!store.getFreight().equals(createOrderVo.getOrderFreight())){
////            throw new SxkfException(500,"商品总价(需前端进行计算):"+createOrderVo.getTotalPrice()+"后端计算价格:"+orderTotalPrice);
//            throw new SxkfException(SxkfExceptionEnum.PAY_ERROR);
//        }


        //计算优惠券
        if (createOrderVo.getUserCouponId().equals("0")) {
            order.setDiscountPrice(BigDecimal.ZERO);
        } else {
            UserCoupon userCoupon = userCouponMapper.selectById(createOrderVo.getUserCouponId());
            if (!product.getStoreId().equals(userCoupon.getStoreId())){
                throw new SxkfException("支持所选优惠券商品不存在");
            }
            orderTotalPrice = handleCoupon(orderTotalPrice, userCoupon, order);
        }

        log.info("运费  前端计算:{}后端计算价格:{}",createOrderVo.getTotalPrice(),orderTotalPrice);
        if (createOrderVo.getTotalPrice().compareTo(orderTotalPrice) != 0) {
//            throw new SxkfException(500,"商品总价(需前端进行计算):"+createOrderVo.getTotalPrice()+"后端计算价格:"+orderTotalPrice);
            throw new SxkfException(SxkfExceptionEnum.PAY_ERROR);
        }

        order.setOrderTotalPrice(orderTotalPrice);
        order.setAddressId(createOrderVo.getAddressId());
        save(order);
        orderDetail.setUserId(order.getUserId());
        orderDetail.setOrderId(order.getId());
        orderDetailService.save(orderDetail);

        OrderRecipient orderRecipient = new OrderRecipient();
        Address address = addressMapper.selectById(createOrderVo.getAddressId());
        BeanUtils.copyProperties(address, orderRecipient,"id");
        orderRecipient.setOrderId(order.getId());
        orderRecipientMapper.insert(orderRecipient);

        if (createOrderVo.getPayType().equals("YUE")){

            if (user.getAmount().compareTo(order.getOrderTotalPrice()) < 0){
                throw new SxkfException("余额不足");
            }

//            boolean update = update(new LambdaUpdateWrapper<Order>()
//                    .set(Order::getState, OrderConstant.PAY)
//                    .eq(Order::getOrderNo, order.getOrderNo()));
//            if (update){
                user.setAmount(user.getAmount().subtract(order.getOrderTotalPrice()));
                int updateUserAmount = userMapper.updateById(user);
                if (updateUserAmount == 0){
                    throw new SxkfException("余额支付失败");
                }
            // 存记录
            AmountRecord amountRecord = new AmountRecord();
            amountRecord.setUserId(user.getId());
            amountRecord.setIsAdd("0");
            amountRecord.setPrice(order.getOrderTotalPrice());
            amountRecord.setRemark("余额支付");
            amountRecordService.save(amountRecord);
//            }
            paySuccess(order);
                return "success";
        }
        return getPayResult(order);
    }

    private Order initOrder(CreateOrderVo createOrderVo){
        Order order = new Order();
        String orderNo = OrderUtil.creatOrder();
        order.setOrderNo(orderNo);
        order.setUserId(createOrderVo.getUserId());
        order.setState(OrderConstant.NO);
        order.setRemark(createOrderVo.getRemark());
        order.setOrderType("1".equals(createOrderVo.getIsTeam())?"1":"0");
        order.setSpellOutId(createOrderVo.getSpellOutId());
        return order;
    }

    @NotNull
    private BigDecimal handleCoupon(BigDecimal orderTotalPrice, UserCoupon userCoupon, Order order) {
        if (orderTotalPrice.compareTo(userCoupon.getCouponMinPrice()) < 0) {
            throw new SxkfException(500, "优惠券未满足下限无法使用");
        }
        orderTotalPrice = orderTotalPrice.subtract(userCoupon.getCouponPrice());
        if (orderTotalPrice.compareTo(BigDecimal.ZERO) < 0) {
            orderTotalPrice = BigDecimal.ZERO;
        }
        userCoupon.setState(CommonConstant.USED);
        userCouponMapper.updateById(userCoupon);
        order.setDiscountPrice(userCoupon.getCouponPrice());
        return orderTotalPrice;
    }


    @Override
    public String toPay(String orderId,String payType) {
        Order order = getById(orderId);
        if (!order.getState().equals(OrderConstant.NO)){
            throw new SxkfException("订单状态已发生变化");
        }
        String result = redisUtils.get(payType + orderId);
        if (result == null){
            order.setPayType(payType);
            return getPayResult(order);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancel(String orderId) {
        Order order = getById(orderId);
        if (CheckEmptyUtil.isEmpty(order) || !Objects.equals(OrderConstant.NO,order.getState())){
            throw new SxkfException(500,"订单状态异常");
        }
        order.setState(OrderConstant.CANCEL);
        updateById(order);

        handleFailOrder(order);
    }

    @Override
    public void refundOrder(String orderNo, BigDecimal refundPrice) {
        Order order = getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNo, orderNo));
        if (CheckEmptyUtil.isEmpty(order) || Objects.equals(OrderConstant.NO,order.getState())){
            throw new SxkfException(500,"订单状态异常");
        }
        order.setState(OrderConstant.REFUND);
        updateById(order);

        refundService.update(new LambdaUpdateWrapper<Refund>()
                .set(Refund::getState,"1")
                .eq(Refund::getState,"0")
                .eq(Refund::getOrderNo, orderNo));

        handleFailOrder(order);

        if (order.getPayType().equals("YUE")){
            User user = userMapper.selectById(order.getUserId());
            userMapper.update(null,new LambdaUpdateWrapper<User>()
                    .setSql("amount = amount + " + refundPrice)
                    .eq(User::getId,user.getId())
            );
            // 存记录
            AmountRecord amountRecord = new AmountRecord();
            amountRecord.setUserId(user.getId());
            amountRecord.setIsAdd("1");
            amountRecord.setPrice(order.getOrderTotalPrice());
            amountRecord.setRemark("订单退款到余额");
            amountRecordService.save(amountRecord);
        }else if (order.getPayType().equals("WX")){
            WxPayUtils.refundOrderV3(orderNo,OrderUtil.creatOrder(),order.getOrderTotalPrice(),refundPrice);
        }else if (order.getPayType().equals("ZFB")){
            AliPayUtil.refund(orderNo,order.getOrderTotalPrice().toString());
        }else {
            throw new SxkfException(SxkfExceptionEnum.PAY_TYPE_ERROR);
        }

    }

    @Override
    public void paySuccess(Order order){
        //修改订单状态
        order.setState(OrderConstant.PAY);
        order.setPayTime(new Date());
        updateById(order);

        //给店铺分账
        List<OrderDetail> orderDetails = orderDetailService.list(new LambdaQueryWrapper<OrderDetail>().eq(OrderDetail::getOrderId, order.getId()));
        Map<String, List<OrderDetail>> storeOrderMap = orderDetails.stream().collect(Collectors.groupingBy(OrderDetail::getStoreId));
        storeOrderMap.forEach((key,value)->{
            Store store = storeMapper.selectById(key);
            // 这里分账需要扣费吗
            double rate;
            if (null != store.getRate()){
                rate = store.getRate();
            }else {
                rate = Double.parseDouble(sysConfigService.getValue(store.getType().equals("1")?"wholesale":"online"));
            }
            BigDecimal storeOrderPrice = value.stream().map(OrderDetail::getProductPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            store.setAmount(store.getAmount().add(storeOrderPrice.multiply(BigDecimal.valueOf(1-rate))));
            storeMapper.updateById(store);
        });

        // 处理拼团逻辑
        if ("1".equals(order.getOrderType()) && CheckEmptyUtil.isNotEmpty(order.getSpellOutId())){
            if ("0".equals(order.getSpellOutId())){
                //开团
                SpellOut spellOut = new SpellOut();
                spellOut.setProductId(orderDetails.get(0).getProductId());
                spellOut.setCreateId(order.getUserId());
                String spellOutId = spellOutService.create(spellOut);
                order.setSpellOutId(spellOutId);
                updateById(order);
            }{
                // todo 是不是少了个else
                //参团
                spellOutService.join(order.getSpellOutId(),order.getUserId());
            }
        }
    }

    @Override
    public Order getOrderDetail(String orderId) {
        if (CheckEmptyUtil.isEmpty(orderId)){
            log.info("orderid:{}",orderId);
            return null;
        }
        Order order = getById(orderId);
        List<OrderDetail> orderDetails = orderDetailService.list(new LambdaQueryWrapper<OrderDetail>().eq(OrderDetail::getOrderId, order.getId()));
        OrderRecipient orderRecipient = orderRecipientMapper.selectOne(new LambdaQueryWrapper<OrderRecipient>().eq(OrderRecipient::getOrderId, order.getId()));

        OrderDetail orderDetail = orderDetails.get(0);
        Store store = storeMapper.selectById(orderDetail.getStoreId());
        order.setStoreName(store.getName());
        order.setStoreAvatar(store.getAvatar());
        order.setStoreId(store.getId());

        order.setOrderDetails(orderDetails);
        order.setOrderRecipient(orderRecipient);

        AfterSaleOrder afterSaleOrder = afterSaleOrderMapper.selectOne(new LambdaQueryWrapper<AfterSaleOrder>()
                .eq(AfterSaleOrder::getOrderId, order.getId())
                .orderByDesc(AfterSaleOrder::getCreateTime)
                .last("limit 1")
        );
        if (!CheckEmptyUtil.isEmpty(afterSaleOrder)){
            order.setAfterSaleOrder(afterSaleOrder);
        }


        if (order.getOrderType().equals("1")){
            SpellOut spellOut = spellOutService.getById(order.getSpellOutId());
            order.setSpellOutState(spellOut.getState());
            Date createTime = spellOut.getCreateTime();
            Date endTime = spellOut.getEndTime();
            order.setLastTime(endTime.getTime() - createTime.getTime());
        }

        return order;
    }

    @Override
    public IPage<Order> userGetList(Integer pageNo, Integer pageSize, String userId, String orderId, String state) {

        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getUserId, userId);
        if (CheckEmptyUtil.isNotEmpty(state)){
            if ("5".equals(state)){
                wrapper.in(Order::getState, OrderConstant.AFTER_SALE, OrderConstant.REFUND, OrderConstant.REJECT);
            }else {
                wrapper.eq(Order::getState, state);
            }
        }
        wrapper.eq(Order::getOrderType,"0");
        wrapper.like(CheckEmptyUtil.isNotEmpty(orderId),Order::getId,orderId);
        wrapper.orderByDesc(Order::getCreateTime);

        Page<Order> page = page(new Page<>(pageNo, pageSize), wrapper
        );

        page.getRecords().forEach(item -> {
            List<OrderDetail> orderDetailList = orderDetailService.list(new LambdaQueryWrapper<OrderDetail>()
                    .eq(OrderDetail::getOrderId, item.getId()));
            Store store = storeMapper.selectById(orderDetailList.get(0).getStoreId());
            item.setOrderDetails(orderDetailList);
//            item.setStore(store);

            item.setStoreName(store.getName());
            item.setStoreAvatar(store.getAvatar());

//            OrderRecipient orderRecipient = orderRecipientMapper.selectOne(new LambdaQueryWrapper<OrderRecipient>()
//                    .eq(OrderRecipient::getOrderId, item.getId()));
//
//            item.setOrderRecipient(orderRecipient);

        });

        return page;
    }

    @Override
    public IPage<Order> busGetList(Integer pageNo, Integer pageSize, String storeId, String orderId, String spellOut, String state) {


        Page<Order> page = new Page<>(pageNo, pageSize);
        if (CheckEmptyUtil.isEmpty(storeId)){
            return page;
        }
        Store store = storeMapper.selectOne(new LambdaQueryWrapper<Store>()
                .eq(Store::getId, storeId));
        // test判断好奇怪，这里先用boolean
        Boolean so = false;
        if (CheckEmptyUtil.isNotEmpty(spellOut)){
            so = spellOut.equals("1")? true : false;
        }


        Long count = baseMapper.getCount(state,store.getId(),orderId,so);
        page.setTotal(count);
        Long pages = count / pageSize;
        page.setPages(count%pageSize == 0 ? pages : pages+1);
        // state判空
        if (CheckEmptyUtil.isEmpty(state)){
            state = null;
        }
        List<Order> res = baseMapper.busUserGetOrder((pageNo - 1) * pageSize,pageSize,state,store.getId(),orderId,so);
        res.forEach(item -> {
            List<OrderDetail> orderDetailList = orderDetailService.list(new LambdaQueryWrapper<OrderDetail>()
                    .eq(OrderDetail::getOrderId, item.getId()));
            item.setOrderDetails(orderDetailList);


//            item.setStore(store);


//            OrderRecipient orderRecipient = orderRecipientMapper.selectOne(new LambdaQueryWrapper<OrderRecipient>()
//                    .eq(OrderRecipient::getOrderId, item.getId()));
//
//            item.setOrderRecipient(orderRecipient);

        });
        page.setRecords(res);
        return page;
    }

    @Override
    public IPage<Order> spellOutList(Integer pageNo, Integer pageSize, String userId, String orderState, String spellOutState) {


        Integer offset = (pageNo - 1) * pageSize;
        boolean emptyOrderState = CheckEmptyUtil.isNotEmpty(orderState);
        boolean emptySpellOutState = CheckEmptyUtil.isNotEmpty(spellOutState);
        boolean equals = spellOutState.equals("1");
        Long count = baseMapper.spellOutCount(userId,orderState,emptyOrderState,spellOutState,emptySpellOutState,equals);
        List<Order> records = baseMapper.spellOutList(offset,pageSize,userId,orderState, emptyOrderState,spellOutState, emptySpellOutState,equals);


        records.forEach(item -> {
            List<OrderDetail> orderDetailList = orderDetailService.list(new LambdaQueryWrapper<OrderDetail>()
                    .eq(OrderDetail::getOrderId, item.getId()));
            Store store = storeMapper.selectById(orderDetailList.get(0).getStoreId());
            item.setOrderDetails(orderDetailList);
//            item.setStore(store);

            item.setStoreName(store.getName());
            item.setStoreAvatar(store.getAvatar());

            OrderRecipient orderRecipient = orderRecipientMapper.selectOne(new LambdaQueryWrapper<OrderRecipient>()
                    .eq(OrderRecipient::getOrderId, item.getId()));

            item.setOrderRecipient(orderRecipient);

            // 拼团头像
            ArrayList<String> list = new ArrayList<>();
            SpellOut spellOut = spellOutService.getById(item.getSpellOutId());
            String[] userIdArray = spellOut.getJoinUserList().split(",");
            List<String> userIdList = Arrays.asList(userIdArray);
            List<User> users = userMapper.selectBatchIds(userIdList);
            users.forEach(user -> {
                list.add(user.getAvatar());
            });
            item.setSpellOutAvatar(list);


        });


        Page<Order> page = new Page<>(pageNo, pageSize);

        page.setTotal(count);
        Long pages = count / pageSize;
        page.setPages(count%pageSize == 0 ? pages : pages+1);
        page.setRecords(records);


        return page;
    }

    @Override
    public Boolean deliver(DeliverOrderVo deliverOrderVo) {

        Order order = getById(deliverOrderVo.getOrderId());

        if (CheckEmptyUtil.isEmpty(order) || Objects.equals(OrderConstant.NO,order.getState())){
            throw new SxkfException(500,"订单状态异常");
        }

        // 待发货 状态改为 运输中
        // 填充 物流信息
        boolean update = update(new LambdaUpdateWrapper<Order>()
                .set(Order::getExpress, deliverOrderVo.getExpress())
                .set(Order::getExpressNo, deliverOrderVo.getExpressNo())
                .set(Order::getState, OrderConstant.DELIVERING)
                .eq(Order::getState,OrderConstant.PAY)
                .eq(Order::getId, order.getId()));

        return update;
    }

    @Override
    public Boolean rerv(String userId, String orderId) {

        Order order = getById(orderId);
        if (CheckEmptyUtil.isEmpty(userId) || !Objects.equals(userId,order.getUserId())){
            throw new SxkfException("参数异常");
        }

        if (!CheckEmptyUtil.isEmpty(order) &&
                Objects.equals(OrderConstant.DELIVERING,order.getState()) ){

            boolean update = update(new LambdaUpdateWrapper<Order>()
                    .set(Order::getState, OrderConstant.FINISH)
                    .eq(Order::getId, orderId));
            return update;

        }
        throw new SxkfException("订单异常");
    }

    @Override
    public Boolean refund(Refund refund) {
        Refund one = refundService.getOne(new LambdaQueryWrapper<Refund>()
                .eq(Refund::getOrderNo, refund.getOrderNo())
                .eq(Refund::getUserId, refund.getUserId())
        );
        if (!CheckEmptyUtil.isEmpty(one)){
            if (one.getState().equals("0")){
                throw new SxkfException("退款已申请");
            }
            if (one.getState().equals("1")){
                throw new SxkfException("已成功退款");
            }
        }
        Order order = getOne(new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderNo, refund.getOrderNo()));
        if (CheckEmptyUtil.isEmpty(order) || Objects.equals(OrderConstant.NO,order.getState())){
            throw new SxkfException(500,"订单状态异常");
        }
        // 状态(0=已申请 1=成功退款 2=驳回退款)
        refund.setState("0");
        // 预计时间：三天内
        refund.setExpectTime(DateUtil.offsetDay(new Date(),3));
        boolean save = refundService.save(refund);
        return save;
    }

    @Override
    public Boolean reject(String refundId) {
        Refund refund = refundService.getById(refundId);
        if (CheckEmptyUtil.isEmpty(refund) || !Objects.equals("0",refund.getState())){
            throw new SxkfException(500,"退款申请状态异常");
        }
        boolean update = refundService.update(new LambdaUpdateWrapper<Refund>()
                .set(Refund::getState, "2")
                .eq(Refund::getId, refundId));
        return update;
    }

    @Override
    public String refundStatus(String refundId) {
        Refund refund = refundService.getById(refundId);
        if (!CheckEmptyUtil.isEmpty(refund)){
            if (refund.getState().equals("0")){
                return "已申请";
            }else if (refund.getState().equals("1")){
                return "成功退款";
            }else if (refund.getState().equals("2")){
                return "驳回退款";
            }
        }
        return "状态异常:"+refund.getState();
    }

    @Override
    public Boolean delete(String orderId) {

//        Order order = getById(orderId);
//        if (CheckEmptyUtil.isEmpty(order) || !Objects.equals(OrderConstant.NO,order.getState())){
//            throw new SxkfException(500,"该订单所处状态无法删除");
//        }

        boolean remove = removeById(orderId);

        return remove;

    }

    @Override
    public void notice(String orderId) {

        Order order = getById(orderId);
        Store store = storeMapper.selectById(order.getStoreId());
        SysUser sysUser = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getStoreId, store.getId()));

        messageService.notice(order.getUserId(),sysUser.getId(),order.getOrderNo());

    }

    @Override
    public IPage<OrderDetail> backSpellOutList(Integer pageNo, Integer pageSize, String busUserId, String orderState, String spellOutState) {

        // busUserId 查出来> 商家用户id  查出来> 商品

        SysUser sysUser = sysUserMapper.selectById(busUserId);

        IPage<Order> page = baseMapper.backSpellOutList(new Page<Order>(pageNo,pageSize),sysUser.getStoreId(),orderState,spellOutState);
//        IPage<OrderDetail> page = orderDetailMapper.backSpellOutList(new Page<OrderDetail>(pageNo,pageSize),sysUser.getStoreId(),orderState,spellOutState);

        List<String> orderIdList = page.getRecords().stream()
                .map(Order::getId)
                .collect(Collectors.toList());

        List<OrderDetail> orderDetails = orderDetailMapper.selectList(new LambdaQueryWrapper<OrderDetail>()
                .in(OrderDetail::getOrderId, orderIdList));

        IPage<OrderDetail> orderDetailIPage = new Page<>();
        BeanUtils.copyProperties(page,orderDetailIPage);
        orderDetailIPage.setRecords(orderDetails);

        return orderDetailIPage;
    }

    private String getPayResult(Order order){


        if (order.getOrderTotalPrice().compareTo(BigDecimal.ZERO) <= 0) {
            //直接走回调并通知前端支付成功
            paySuccess(order);
            return null;
        }

        String result;
        if ("WX".equals(order.getPayType())) {
            result = WxPayUtils.createOrderV3(order.getOrderNo(), order.getOrderTotalPrice(), "", null);
            redisUtils.set("WX" + order.getId(), JSON.toJSONString(result), 15 * 60);
        } else if ("ZFB".equals(order.getPayType())) {
            result = AliPayUtil.pay("", order.getOrderNo(), order.getOrderTotalPrice());
            redisUtils.set("ZFB" + order.getId(), JSON.toJSONString(result), 15 * 60);
        } else if ("YUE".equals(order.getPayType())) {
            User user = userMapper.selectById(order.getUserId());
            if (user.getAmount().compareTo(order.getOrderTotalPrice()) < 0){
                throw new SxkfException("余额不足");
            }
            user.setAmount(user.getAmount().subtract(order.getOrderTotalPrice()));
            int updateUserAmount = userMapper.updateById(user);
            if (updateUserAmount == 0){
                throw new SxkfException("余额支付失败");
            }
            paySuccess(order);
            return "success";
        } else {
            throw new SxkfException(SxkfExceptionEnum.PAY_TYPE_ERROR);
        }
        return result;
    }

    private void handleFailOrder(Order order) {
        //如果使用优惠券则退回
        if (Objects.equals(OrderConstant.NO, order.getState()) && !order.getUserCouponId().equals("0")){
            UserCoupon userCoupon = userCouponMapper.selectById(order.getUserCouponId());
            userCoupon.setState(CommonConstant.ENABLE);
            userCouponMapper.updateById(userCoupon);
        }

        //返还商品库存
        List<OrderDetail> orderDetails = orderDetailService.list(new LambdaQueryWrapper<OrderDetail>()
//                .select(OrderDetail::getProductSpecId)
                .eq(OrderDetail::getOrderId, order.getId()));
        orderDetails.forEach(item->{
            ProductSpec productSpec = productSpecMapper.selectById(item.getProductSpecId());
            productSpec.setStock(productSpec.getStock()+item.getProductCount());
            productSpecMapper.updateById(productSpec);
        });

        // 商家扣余额
        storeMapper.update(null,new LambdaUpdateWrapper<Store>()
                .setSql("amount = amount -" + order.getOrderTotalPrice())
                .eq(Store::getId, order.getStoreId())
        );
    }

    private OrderDetail getOrderDetail(Integer productCount, Product product, ProductSpec productSpec) {
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setProductId(product.getId());
        orderDetail.setStoreId(product.getStoreId());
        orderDetail.setProductSpecId(productSpec.getId());
        orderDetail.setProductSpec(productSpec.getSpecAttribute());
        orderDetail.setProductName(product.getName());
        orderDetail.setProductPrice(productSpec.getSalePrice());
        orderDetail.setProductImg(product.getImageUrl());
        orderDetail.setProductCount(productCount);
        return orderDetail;
    }
}
